package com.project.fortuneteller.service.impl;

import com.project.fortuneteller.config.DivineConfig;
import com.project.fortuneteller.config.TryConfig;
import com.project.fortuneteller.pojo.dto.DivineDto;
import com.project.fortuneteller.pojo.vo.PlumBlossomVo;
import com.project.fortuneteller.mappers.DivinatoryDetailsMapper;
import com.project.fortuneteller.pojo.DivinatoryDetails;
import com.project.fortuneteller.service.DivineWayService;
import com.project.fortuneteller.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *  实现 64卦的演示 和 三种占卜的模拟
 *
 *    1.  易经 64 卦的 演示
 *    2.  大衍噬法
 *    3.  金钱卦
 *    4.  梅花易数
 */
@Slf4j
@Service
public class DivineWayServiceImpl implements DivineWayService {

    @Autowired
    private DivinatoryDetailsMapper divinatoryDetailsMapper;

    @Autowired
    private ChangeUtils changeUtils;


    @Autowired
    private DivineConfig divineConfig;


    /**
     * 64 卦的演示
     * @param target
     * @return
     */
    @Override
    public Result getByDivine(String target){

        DivinatoryDetails result = divinatoryDetailsMapper.getById(target);
        if(result!=null){
            return Result.success(result);
        }
        return Result.error("输入错误 ，不在 64卦的范围之内");
    }


    /**
     *
     * 大衍噬法 占卜方式的代码模拟实现
     * @return 返回的结果为 两个卦， 一个是 本卦 表示事务发展的当前现状，
     *                        还有一个边卦表示事务发展的下一个阶段的变卦。
     */
    @Override
    public Result getDeductionImitate(){

        // 创建一个新的Hexagram实例
        StringBuilder hexagram = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            // 六次大衍筮法步骤
            hexagram.append(DayanMethodUtil.calculateYao());
            // 使用大衍筮法生成爻并添加到Hexagram
        }
        //本卦
        String baseValue = hexagram.toString();
        //获取变卦
        StringBuffer changeValueStr = new StringBuffer();
        // 获取本卦
        StringBuffer baseValueStr = new StringBuffer();
      // 获取结果
        DivineDto divineDtoRes = getDivines(baseValue,baseValueStr,changeValueStr);

        // 获取 文件名称
        log.info(baseValue);
        // 返回生成的Hexagram
        return Result.success(divineDtoRes);
    }

    /**
     * 获取本卦和变卦的操作
     * @param baseValue
     * @param baseValueStr
     * @param changeValueStr
     * @return
     */
    public DivineDto getDivines(String baseValue,StringBuffer  baseValueStr,StringBuffer  changeValueStr){

        for(int i = 0; i< baseValue.length(); i ++) {
            char val = baseValue.charAt(i);
            if (val == '9') {
                //转化为 0 或 1
                changeValueStr.append(  (('6' -'0')%2));
            } else if (val == '8') {
                // 转化为 0 或 1
                changeValueStr.append( (('7' -'0')%2));
            } else {
                changeValueStr.append(baseValue.charAt(i)%2);
            }
            baseValueStr.append((baseValue.charAt(i) - '0') % 2);
        }
        DivinatoryDetails baseDetail = divinatoryDetailsMapper.getById(baseValueStr.toString());
        DivinatoryDetails changeDetail = divinatoryDetailsMapper.getById(changeValueStr.toString());

        // 获取结果
        DivineDto divineDtoRes = new DivineDto();

        // 获取卦象的名称
        divineDtoRes.setBaseName(baseDetail.getDivinatoryName());
        divineDtoRes.setChangeName(changeDetail.getDivinatoryName());

        // 获取本卦的结果及对应的值
        divineDtoRes.setBase(baseValueStr.toString());
        // 获取对应卦象的解释
        divineDtoRes.setBaseExplain(baseDetail.getDivinatoryExplain());
        divineDtoRes.setChangeExplain(changeDetail.getDivinatoryExplain());

        //获取变卦的值 及相关的描述信息
        divineDtoRes.setChange(changeValueStr.toString());
        return divineDtoRes;
    }

    /**
     * 金钱卦 占卜方式的代码模拟实现
     * @return
     */
    @Override
    public Result getMoneyImitate(){
        // 生成一个金钱卦
         // 创建一个新的Hexagram实例
        StringBuilder hexagram = new StringBuilder();
        for (int i = 0; i < 6; i++) { // 六次抛掷铜钱
            hexagram.append(CoinTossUtil.tossCoins()); // 添加爻结果到Hexagram
        }
        //获取变卦
        StringBuffer changeValueStr = new StringBuffer();
        // 获取本卦
        StringBuffer baseValueStr = new StringBuffer();
        // 获取 用 0和 1表示的 本卦和 互卦
        DivineDto divines = getDivines(hexagram.toString(), baseValueStr, changeValueStr);

        return Result.success(divines); // 返回生成的Hexagram
    }

    /**
     * 梅花易数 占卜方式的代码模拟实现
     *                   默认是新历日期
     * @param plumBlossomVo
     * @return
     */
     @Override
    public Result getPlumBlossomImitate(PlumBlossomVo plumBlossomVo) throws ParseException {

         /**
          *  上卦 年+月+日 mod 8  =  a  上卦
          *  下卦 年+月+日+时 mod 8  =  b 下卦
          *   下卦 年+月+日+时 mod 6  = c  动爻
          *   上+下卦  = 本卦(事物表象)   本卦  + 动爻 = 变卦(事物发展趋势)
          *   本卦 上三爻 + 下三爻 = 互卦(事物本质)
          */

         System.out.println(divineConfig.items.size());

         int hour = plumBlossomVo.getHour();
         int day = plumBlossomVo.getDay();
         int month = plumBlossomVo.getMonth();
         int year = plumBlossomVo.getYear();

         Calendar today = Calendar.getInstance();
         today.setTime(new java.util.Date());//加载当前日期
         SimpleDateFormat chineseDateFormat = new SimpleDateFormat(
                 "yyyy-MM-dd");

         today.setTime(chineseDateFormat.parse(year+ "-" + month+"-"+ day));//加载自定义日期 Lunar
         // 转化为农历进行运算
         Lunar lunar = new Lunar(today);

          //  年份
         String cyclical = lunar.cyclical();
         // 年份
         year =   Branche12Util.branche12Map.get(cyclical.charAt(1) + "");

         String monthAndDay = lunar.toString();
         String[] months = monthAndDay.split("月");

         /**
          * 匹配 月 和 日
          */
         for (int i = 0; i < Branche12Util.UDayList.length; i++) {
             if(months[0].equals(Branche12Util.UDayList[i])   ){
                   month =  i;
             }
             if(months[1].equals(Branche12Util.UDayList[i])   ){
                  day =  i;
             }
         }
         // 上卦
         int up =  (year+ month+ day) % 8;
         // 下卦
         int down = (year+ month+ day + hour/2 ) % 8;
         // 动爻
         int don = (year + month+ day + hour/2) %6;

         // 本卦
         String baseChange =  changeUtils.Change8List[up]+ changeUtils.Change8List[down];

         StringBuffer baseBuffer = new StringBuffer(baseChange);

         if(baseChange.charAt(6- don) == '0' ){
             baseBuffer.setCharAt(6- don,'1');
         }
         if(baseChange.charAt(6- don) == '1' ){
             baseBuffer.setCharAt(6- don,'0');
         }
         // 变卦
         String changeChange = baseBuffer.toString();

         // 互卦
         String EndChange =  baseChange.substring(1,4) + baseChange.substring(2,5);

         /**
          * 这里为了提高开发效率， 暂时 直接使用 List
          */
         List<DivinatoryDetails> divinatoryDetailsList= new ArrayList<>();
         /**
          *
          */
         divinatoryDetailsList.add( divinatoryDetailsMapper.getById(baseChange));
         divinatoryDetailsList.add( divinatoryDetailsMapper.getById(changeChange));
         divinatoryDetailsList.add( divinatoryDetailsMapper.getById(EndChange));
         /**
          * 获取三个卦象的相关信息
          */

         return Result.success(divinatoryDetailsList);
    }





}
